package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.Dto.DishDto;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import com.itheima.reggie.service.SetmealDishService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhoufei
 */
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private SetmealDishService setmealDishService;

    /**
     * 重写菜品新增方法
     * @param dishDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    //此处开启了事物，需要在引导类也加上注解
    public void saveWithFlavor(DishDto dishDto) {
        //1.菜品类的实体属性对应的数据存储到数据库的菜品表中
        this.save(dishDto);

        //2.添加dish表中没有的属性
            //2.1添加菜品口味（口味只能存储在口味表中，但是怎么通过菜品表得到该菜品的口，通过观察两张表发现在口味表中存在菜品表的外键Id,这样可以通过菜品id就可以查到该菜品的口味，但是在新增时前端通过Json发送的数据中菜品类的属性值都存在，品味类的属性值只存在name和value的值,口味的属性中菜品的外键Id没有值，这导致在对数据存储口味时，菜品外键没有值，无法存储，因此需要在存储口味时需要为其添加菜品外键Id的值
            //2.1.1获取菜品id
            Long dishId = dishDto.getId();
            //2.1.2获取菜品口味
            List<DishFlavor> flavors = dishDto.getFlavors();
            //2.2对口味添加菜品外键Id的值
           flavors = flavors.stream().map((flavor)->{
                flavor.setDishId(dishId);
                return flavor;
            }).collect(Collectors.toList());
            //3.保存菜品口味到数据表中
            dishFlavorService.saveBatch(flavors);
    }

    /**
     * 重写自定修改方法
     * @param dishDto
     */
    @Override
    public void updateWithFlavor(DishDto dishDto) {
        //1.通过dishService先修改Dish表中的属性
        this.updateById(dishDto);

        //2.要修改口味的信息，设计到两个表，需要先删除原先口味表中存在的口味信息，在把修改的新口味存储到其中
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId,dishDto.getId());
        dishFlavorService.remove(queryWrapper);

        //3.重新插入修改的口味
        List<DishFlavor> flavors = dishDto.getFlavors();
        //3.1为修改的口味添菜品id作为外键id存储到口味表中
        flavors = flavors.stream().map((flavor) -> {
            flavor.setDishId(dishDto.getId());
            return flavor;
        }).collect(Collectors.toList());
        //将修改的口味（带菜品Id）存储到表中
        dishFlavorService.saveBatch(flavors);
    }

    /**
     * 重写删除方法
     * @param ids
     */
    @Override
    public void deleteByIds(List<Long> ids) {
        //1.菜品是否关联套餐信息，通过id查询套餐表
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SetmealDish::getDishId,ids);
        int count = setmealDishService.count(queryWrapper);
        //2.判断套餐表是否存在该菜品
        if (count > 0){
            throw new CustomException("该菜品关联了套餐，无法删除");
        }
        //3.查询该菜品状态
        LambdaQueryWrapper<Dish> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.in(Dish::getId,ids);
        queryWrapper1.eq(Dish::getStatus,1);
        int count1 = this.count(queryWrapper1);
        //判断该是否是启售
        if (count1 > 0){
            throw new CustomException("该菜品是启售状态，无法删除");
        }
        //5.删除该菜品在菜品表和口味表中的信息
            //5.1删除菜品表中的信息
            this.removeByIds(ids);
            //5.2删除口味表中该菜品的口味信息
            LambdaQueryWrapper<DishFlavor> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2.in(DishFlavor::getDishId,ids);
            dishFlavorService.remove(queryWrapper2);
    }

}
